/**
 */
package com.exp.base.util;

import java.util.concurrent.Callable;

import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.CacheManager;
import org.springframework.util.Assert;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import com.exp.base.FastException;


/**
 * Cache工具类
 * @author ThinkGem
 * @version 2013-5-29
 */
public class CacheUtils {
	
	private static CacheManager cacheManager = null;

	private static void check(){
		if (cacheManager == null) {
			CacheManager _cacheManager = SpringUtils.getBean("cacheManager");
			if (_cacheManager != null) {
				cacheManager = _cacheManager;
			}else{
				ExceptionUtils.throwException("spring has not cacheManager");
			}
		}
	}
	public static<T> T getWithCache(String cacheName,Object key,Callable<T> callback){
		Assert.notNull(cacheName, "cacheName 不能为空");
		Assert.notNull(key, "key 不能为空");
		Assert.notNull(callback, "callback 不能为空");
		check();
		Cache cache = cacheManager.getCache(cacheName);
		Assert.notNull(cache, "不存在缓存"+cacheName);
		ValueWrapper valueWrapper = cache.get(key);
		if(valueWrapper==null){
			T value = null ;
			try {
				value = callback.call();
			} catch (Exception e) {
				ExceptionUtils.throwException(e);
			}
			if(value!=null){
				cache.put(key, value);
			}
			return value;
		}else{
			return (T)valueWrapper.get();
		}
	}
	
	/**
	 * 获取缓存
	 * @param cacheName
	 * @param key
	 * @return
	 */
	public static<T> T get(String cacheName, String key) {
		Assert.notNull(cacheName, "cacheName 不能为空");
		Assert.notNull(key, "key 不能为空");
		check();
		Cache cache = cacheManager.getCache(cacheName);
		Assert.notNull(cache, "不存在缓存"+cacheName);
		ValueWrapper valueWrapper = cache.get(key);
		if(valueWrapper==null){
			return null;
		}else{
			return (T)valueWrapper.get();
		}
	}

	/**
	 * 写入缓存
	 * @param cacheName
	 * @param key
	 * @param value
	 */
	public static void put(String cacheName, String key, Object value) {
		Assert.notNull(cacheName, "cacheName 不能为空");
		Assert.notNull(key, "key 不能为空");
		check();
		Cache cache = cacheManager.getCache(cacheName);
		Assert.notNull(cache, "不存在缓存"+cacheName);
		cache.put(key, value);
	}

	/**
	 * 从缓存中移除
	 * @param cacheName
	 * @param key
	 */
	public static void remove(String cacheName, String key) {
		Assert.notNull(cacheName, "cacheName 不能为空");
		Assert.notNull(key, "key 不能为空");
		check();
		Cache cache = cacheManager.getCache(cacheName);
		if(cache!=null){
			cache.evict(key);
		}
	}

	/**
	 * 获取缓存
	 * @param cacheName
	 * @param key
	 * @return
	 */
	public static Cache get(String cacheName) {
		Assert.notNull(cacheName, "cacheName 不能为空");
		check();
		Cache cache = cacheManager.getCache(cacheName);
		return cache;
	}

	/**
	 * 从缓存中移除
	 * @param cacheName
	 * @param key
	 */
	public static void remove(String cacheName) {
		Assert.notNull(cacheName, "cacheName 不能为空");
		check();
		Cache cache = cacheManager.getCache(cacheName);
		if(cache!=null){
			cache.clear();
		}
	}

}
